/**servlet listener of framework core module
 * if you want to start the listener, you need to configurate it in web.xml of <listener></listener>
 * by fuzhou huilin corp.ltd @author lms 2016.07.25
 * last update by lms for loading auto task from properties configuratio file and start them
 */
package com.fzrskj.cloud.free.sys.task;

import com.fzrskj.cloud.free.core.tool.CStrTool;
import ms.core.db.ConnectionContext;
import ms.core.support.Task;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.*;

public class CTaskListener implements ServletContextListener {
	private List<Timer> timers = null;
	private Map<String,Task> xmlTask = null;
		
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		timers = new ArrayList<Timer>();
		xmlTask= new HashMap<String,Task>();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

		sce.getServletContext().log("initializing task...");
		//load auto task configuration
		loadTaskXML("/config/task.xml",xmlTask);
		//to load auto task object
		for(Map.Entry<String,Task> mp: xmlTask.entrySet()){
			Task tsk = mp.getValue();
			if ("true".equals(tsk.getEnable().toLowerCase())){
				loadAutoTask(tsk, sce.getServletContext());
			}
		}	
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		xmlTask.clear();
		//to suspend auto task
		for(Timer t: timers) t.cancel();
		sce.getServletContext().log("task finished due to service ended.");
	}

	/**to load auto task configulation from xml
	 * @param fileName xml file
	 * @param tasks Map of Task
	 * @author lms 2016.08.25
	 */
	private void loadTaskXML(String fileName, Map<String,Task> tasks){
		try{
			InputStream in = this.getClass().getResourceAsStream(fileName);
			SAXReader reader = new SAXReader();
			Document doc = reader.read(in);
			Element root = doc.getRootElement();
			List<Element> items = root.elements();
			for(Element item : items){
				Task tsk = new Task();
				tsk.setId(item.attributeValue("id"));
				tsk.setClassName(item.attributeValue("className"));
				tsk.setDescription(item.attributeValue("desc"));
				tsk.setInterval(CStrTool.strToIntDef(item.attributeValue("interval"),1000));
				tsk.setEnable(item.attributeValue("enable"));
				tasks.put(tsk.getId(), tsk);
			}
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//to load one task
	private void loadAutoTask(Task cfgTsk, ServletContext sce){
		try{
			Class<?> cls = Class.forName(cfgTsk.getClassName());
			Constructor<?> cons = cls.getConstructor(ServletContext.class);
			TimerTask tmTsk = (TimerTask) cons.newInstance(sce);
			Timer timer   = new Timer(true);
			timer.schedule(tmTsk, new Date(), cfgTsk.getInterval());
			timers.add(timer);
		}catch(Exception e){
			e.printStackTrace();
		} finally {
			ConnectionContext.closeAllConnection();
		}
	}
}
